/**
 * 碰撞池
 */
if ('function' != typeof LBUtility) {

    throw   'Little Bee core lib not import';
}

var	HitablePool	= function () {
	
	this._pool	= [];
	this._ID	= ++ HitablePool._IDSeed;
}


HitablePool.eventNameList	= [
	'hitablePool.hit',
	'hitablePool.adjacent'
];

HitablePool.isOwnEventName	= function (eventName) {
	
	for (var offset = 0;offset < HitablePool.eventNameList.length;offset ++) {
		
		if (HitablePool.eventNameList[offset] == eventName) {
			
			return	true;
		}
	}
	
	return	false;
}

/**
 * 注册事件名
 */
HitablePool.initailize	= function () {
	
	for (var offset = 0;offset < HitablePool.eventNameList.length;offset ++) {

		LBEvent.registName(HitablePool.eventNameList[offset]);
	}
}
 
LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEventDispatcher.js');
LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEventListener.js');
LBUtility.getInstance().registSelector('lib/core/EventDispatcher/LBEvent.js');

HitablePool._IDSeed	= 0;

HitablePool.prototype.appendShape	= function (hitableShape) {
	
	this._pool.push(hitableShape);
}

HitablePool.prototype.unlinkShapeByIndex	= function (index) {
	
	this._pool.splice(index, 1);
}

HitablePool.prototype.getShapeByIndex	= function (index) {
	
	return	this._pool[index];
}

HitablePool.prototype.unlinkShapeBy	= function (hitableShape) {
	
	for (var offset = 0;offset < this._pool.length;offset ++) {
		
		if (hitableShape === this._pool[offset]) {
			
			this.unlinkShapeByIndex(offset);
			break;
		}
	}
}

HitablePool.prototype._getPositionMap	= function () {
	
	var	positionMap				= {};
	
	for (var offsetPool = 0;offsetPool < this._pool.length;offsetPool ++) {
		
		var	matrix		= this.getShapeByIndex(offsetPool).getMatrix();
		var	position	= this.getShapeByIndex(offsetPool).getPosition();
		this.getShapeByIndex(offsetPool).doDebug();
		
		for (var offsetMatrixRow = 0;offsetMatrixRow < matrix.length;offsetMatrixRow ++) {
		
			for (var offsetMatrixColumn = 0;offsetMatrixColumn < matrix[offsetMatrixRow].length;offsetMatrixColumn ++) {
			
				if (matrix[offsetMatrixRow][offsetMatrixColumn]) {
				
					var	indexPosition			= (position.x + offsetMatrixRow) + ':' + (position.y + offsetMatrixColumn);
					positionMap[indexPosition]	= 'undefined' == typeof positionMap[indexPosition]	? []	: positionMap[indexPosition];
					positionMap[indexPosition].push(offsetPool);
				}
			}
		}
	}
	
	return	positionMap;
}

HitablePool.prototype._hitTest	= function (positionMap, indexPosition) {
	
	if (positionMap[indexPosition].length <= 1) {
		
		return	;
	}
	
	LBEventDispatcher
		.getInstance()
		.triggerEvent(
			new LBEvent({
				"name"		: 'hitablePool.hit',
				"target"	: this,
				"id"		: this._ID,
				"indexList"	: positionMap[indexPosition]
			})
		);
	
	for (var offsetPool = 0;offsetPool < positionMap[indexPosition].length;offsetPool ++) {
		
		var	shape	= this.getShapeByIndex(offsetPool);
		
		if ('undefined' != typeof shape) {
			
			LBEventDispatcher
				.getInstance()
				.triggerEvent(
					new LBEvent({
						"name"		: 'hitableShape.hit',
						"target"	: shape,
						"id"		: shape.getID(),
						"indexList"	: positionMap[indexPosition]
					})
				);
		}
	}
}

HitablePool.prototype._adjacentTest	= function (positionMap, indexPosition) {

	var	deltaPosition	= [
		[-1	, -1],
		[0	, -1],
		[1	, -1],
		[1	, 0],
		[1	, 1],
		[0	, 1],
		[-1	, 1],
		[-1	, 0]
	];

	var	positionPoint	= indexPosition.split(':');
	
	for (var offsetPoolCurrent = 0;offsetPoolCurrent < positionMap[indexPosition].length;offsetPoolCurrent ++) {
	
		var	shape	= this.getShapeByIndex(positionMap[indexPosition][offsetPoolCurrent]);

		for (offsetPositionAdjacent = 0;offsetPositionAdjacent < deltaPosition.length;offsetPositionAdjacent ++) {
			
			var	positionAdjacent	= (parseInt(positionPoint[0]) + deltaPosition[offsetPositionAdjacent][0]) +
								':' + (parseInt(positionPoint[1]) + deltaPosition[offsetPositionAdjacent][1]);
			
			if ('undefined' == typeof positionMap[positionAdjacent] || positionMap[positionAdjacent].length == 0) {
				
				continue;
			}
							
			for (var offsetPoolAdjacent = 0;offsetPoolAdjacent < positionMap[positionAdjacent].length;offsetPoolAdjacent ++) {
				
				var	shapeAdjacent	= this.getShapeByIndex(positionMap[positionAdjacent][offsetPoolAdjacent]);
				
				if ('undefined' != typeof shape && 'undefined' != typeof shapeAdjacent && shape != shapeAdjacent && indexPosition != positionAdjacent) {
					
					LBEventDispatcher
						.getInstance()
						.triggerEvent(
							new LBEvent({
								"name"				: 'hitableShape.adjacent',
								"target"			: shape,
								"id"				: shape.getID(),
								"indexAdjacentList"	: positionMap[positionAdjacent]
							})
						);
				}
			}
		}
		
	}
}

HitablePool.prototype.hitTest	= function () {
	
	var	positionMap	= this._getPositionMap();
	
	for (var indexPosition in positionMap) {
		
		this._hitTest(positionMap, indexPosition);
		this._adjacentTest(positionMap, indexPosition);
	}
}
